package com.peakmain.wanandroid.netmodule.net.http;


import com.blankj.utilcode.util.LogUtils;
import com.peakmain.wanandroid.netmodule.net.http.callback.RequestCallBack;
import com.peakmain.wanandroid.netmodule.net.http.util.JsonUtil;
import com.peakmain.wanandroid.netmodule.utils.log.JsonLog;

import org.json.JSONObject;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Set;
import java.util.concurrent.Executor;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.Response;

/**
 * author ：Peakmain
 * version : 1.0
 * createTime：2020/2/22
 * mail:2726449200@qq.com
 * describe：okHttp请求响应实体类
 */
public class OkHttpResponse<T> {
    private static final String CODE = "code";
    private static final String PAGER = "pager";

    private RequestCall mRequestCall;
    private RequestCallBack mCallBack;
    private Executor mPlatform;


    public OkHttpResponse(RequestCall requestCall, RequestCallBack<T> callBack) {
        this.mRequestCall = requestCall;
        this.mCallBack = callBack;
        mPlatform = OkHttpManager.getInstance().getDelivery();
    }

    /**
     * 执行okHttp请求 异步任务
     */
    public void executeOkHttp() {
        final int id = mRequestCall.getOkHttpRequest().getId();
        final ResponseCode responseData = new ResponseCode();
        mRequestCall.getCall().enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                outPutRequestMessage(call.request(), null);
                responseData.setCall(call);
                if(e instanceof SocketTimeoutException){
                    responseData.setCode(ResponseCode.NETWORK_TIMEOUT);
                }
                sendExceptionCallback(responseData, e, id);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                outPutRequestMessage(call.request(), response);
                responseData.setCall(call);
                // 处理 http 层
                final int httpCode = response.code();
                String httpResponseStr = null;
                try {
                    httpResponseStr = response.body().string();
                    responseData.setCode(httpCode);
                    responseData.setMsg(response.message());
                    if (httpCode == ResponseCode.HTTP_CODE_200) {
                        if (httpResponseStr != null) {
                            JSONObject jsonObject = new JSONObject(httpResponseStr);
                            int code = -1;
                            if(jsonObject.has(CODE)){
                                code = jsonObject.optInt(CODE);
                            }
                            //解析分页
                            if(jsonObject.has(PAGER)){
                                PagerBean pager = JsonUtil.getObject(jsonObject.optString(PAGER),PagerBean.class);
                                responseData.setPagerBean(pager);
                            }
                            //code 0  正常 1错误 2 token失效
                            if(code == 0){
                                String dataStr = jsonObject.optString("data", "");
                                responseData.setCode(ResponseCode.CODE_SUCCESS);
                                responseData.setResponse(httpResponseStr);
                                responseData.setResponseStr(dataStr);
                                responseData.setResponseJson(JsonUtil.jsonData(httpResponseStr));
                                T data = (T) mCallBack.parseNetworkResponse(responseData, response);
                                sendSuccessResultCallback(data, responseData, id);
                            }else {
                                String msg = jsonObject.optString("errorMsg", "");
                                responseData.setMsg(msg);
                                responseData.setCode(code);
                                sendFailResultCallback(responseData, id);
                            }
                        } else {
                            sendFailResultCallback(responseData, id);
                        }
                    } else {
                        sendExceptionCallback(responseData, null, id);
                    }
                } catch (Exception e) {
                    //一般为服务器响应成功，但是数据解析错误
                    sendExceptionCallback(responseData, e, id);
                }

            }
        });
    }

    /**
     * 请求异常错误
     */
    public void sendExceptionCallback(final ResponseCode responseCode, final Exception e, final int id) {
        if (mCallBack == null) {
            return;
        }
        mPlatform.execute(new Runnable() {
            @Override
            public void run() {
                mCallBack.onError(responseCode, e, id);
                mCallBack.onAfter(id);
            }
        });
    }

    /**
     * 请求异常错误
     */
    public void sendFailResultCallback(final ResponseCode responseCode, final int id) {
        if (mCallBack == null) {
            return;
        }
        mPlatform.execute(new Runnable() {
            @Override
            public void run() {
                mCallBack.onFailure(responseCode, id);
                mCallBack.onAfter(id);
            }
        });
    }

    /**
     * 请求成功回调
     */
    public void sendSuccessResultCallback(final T t, final ResponseCode responseCode, final int id) {
        if (mCallBack == null) {
            return;
        }
        mPlatform.execute(new Runnable() {
            @Override
            public void run() {
                mCallBack.onSuccess(t, responseCode, id);
                mCallBack.onAfter(id);
            }
        });
    }

    /**
     * 输出 OkHttp 请求信息
     */
    private void outPutRequestMessage(Request request, Response response) {
        Headers requestHeadersString = request.headers();
        Set<String> requestNames = requestHeadersString.names();
        StringBuilder sb = new StringBuilder();
        for (String name : requestNames) {
            sb.append(name).append(" ： ").append(requestHeadersString.get(name)).append("\n");
        }
        LogUtils.d(sb.toString());

        if (response != null) {
            Headers responseHeadersString = response.headers();
            Set<String> names = responseHeadersString.names();
            sb = new StringBuilder();
            sb.append("url ： ").append(response.request().url()).append("\n\n");
            sb.append("stateCode ： ").append(response.code()).append("\n");
            for (String name : names) {
                sb.append(name).append(" ： ").append(responseHeadersString.get(name)).append("\n");
            }
            JsonLog.printJson("OkHttpResponse", sb.toString(), "");
            LogUtils.d(sb.toString());
        }
    }
}

